#include "TestGUI.h"
#include "vtkObject.h"
#include "vtkObjectFactory.h"
#include "vtkCommand.h"

#include "vtkSlicerApplication.h"
#include "vtkSlicerModuleLogic.h"
#include "vtkSlicerDataGUI.h"
#include "vtkSlicerModuleCollapsibleFrame.h"

#include "vtkKWWidget.h"
#include "vtkKWFrameWithLabel.h"

#include "EndoscopeWidget.h"

#include "vtkKWUserInterfaceManager.h"
#include "EndoscopeNode.h"
#include "windows.h"
#include "EndoscopeLogic.h"
#include "ifimg.h"
#include "vtkKWTKUtilities.h"
#include <vtkKWMultiColumnListWithScrollbars.h>
#include <vtkKWMultiColumnList.h>
#include <string>
#include <vtkKWEntryWithLabel.h>
#include <vtkKWEntry.h>
#include "VirtualDisplayWidget.h"
#include <vtkMRMLLinearTransformNode.h>
#include "vtkSlicerModelHierarchyLogic.h"
#include "vtkMRMLImageNode.h"
#include "vtkMRMLImageDisplayNode.h"
#include "vtkMRMLEndoscopeImageDisplayNode1.h"
#include "vtkMRMLEndoscopeImageDisplayNode2.h"
#include "vtkMRMLEndoscopeImageDisplayNode3.h"
#include <vtkActor2D.h>
#include <vtkRenderer.h>
#include <vtkJPEGReader.h>
#include <vtkTextureMapToCylinder.h>
#include <strstream>
#include <vtkCellArray.h>
#include "vtkTexureMappingByOrientation.h"
#include <vtkTexture.h>
#include <vtkJPEGReader.h>
#include <vtkBMPWriter.h>
#include "../config.h"
#include <time.h>
#include <strstream>
#include <cv.h>
#include <cxcore.h>
#include <highgui.h>
//---------------------------------------------------------------------------
vtkStandardNewMacro (EndoscopeGUI );
vtkCxxRevisionMacro ( EndoscopeGUI, "$Revision: 1.0 $");

//---------------------------------------------------------------------------
EndoscopeGUI::EndoscopeGUI ( )
{
	Built = false;
	EndoscopeView = NULL;
	EndoscopeIP = NULL;
	CaptureStartButton = NULL;
	ESLogic = NULL;
	CaptureStopButton = NULL;
	OpenDeviceButton = NULL;
	CloseDeviceButton = NULL;
	FrameFrequencyLabel = NULL;
	TestButton = NULL;
	StartTrackingButton = NULL;
	StopTrackingButton = NULL;
	AurorerInitialButton = NULL;
	ReportMultiColumnList = NULL;
	VirtualDisplayWidget = NULL;
	CalibrationBeginButton = NULL;
	CalibrationStopButton = NULL;
	SampleNumLabel = NULL;
	XOffsetEntry = NULL;
	YOffsetEntry = NULL;
	ZOffsetEntry = NULL;
	MySlicerViewerWidget = NULL;
	EndoscopeWindow1 = NULL;
	EndoscopeWindow2 = NULL;
	TextMappingButton = NULL;
	SaveImageButton = NULL;
}


//---------------------------------------------------------------------------
EndoscopeGUI::~EndoscopeGUI ( )
{

	if (this->FrameFrequencyLabel != NULL)
	{
		this->FrameFrequencyLabel->SetParent(NULL);
		this->FrameFrequencyLabel->Delete();
		this->FrameFrequencyLabel = NULL;
	}
	if (this->CaptureStartButton)
	{
		this->CaptureStartButton->SetParent(NULL);
		this->CaptureStartButton->Delete();
		this->CaptureStartButton = NULL;
	}
	if (this->CaptureStopButton)
	{
		this->CaptureStopButton->SetParent(NULL);
		this->CaptureStopButton->Delete();
		this->CaptureStopButton = NULL;
	}
	if (this->OpenDeviceButton)
	{
		this->OpenDeviceButton->SetParent(NULL);
		this->OpenDeviceButton->Delete();
		this->OpenDeviceButton = NULL;
	}
	if (this->CloseDeviceButton)
	{
		this->CloseDeviceButton->SetParent(NULL);
		this->CloseDeviceButton->Delete();
		this->CloseDeviceButton = NULL;
	}

	if (this->EndoscopeView != NULL)
	{
		this->EndoscopeView->SetParent(NULL);
		this->EndoscopeView->Delete();
		this->EndoscopeView = NULL;
	}
	if (this->EndoscopeIP != NULL)
	{
		this->EndoscopeIP->Delete();
		this->EndoscopeIP = NULL;
	}
	if (TestButton != NULL)
	{
		TestButton->SetParent(NULL);
		TestButton->Delete();
		TestButton = NULL;
	}
	if (StartTrackingButton != NULL)
	{
		StartTrackingButton->SetParent(NULL);
		StartTrackingButton->Delete();
		StartTrackingButton = NULL;
	}
	if (StopTrackingButton != NULL)
	{
		StopTrackingButton->SetParent(NULL);
		StopTrackingButton->Delete();
		StopTrackingButton = NULL;
	}
	if (AurorerInitialButton != NULL)
	{
		AurorerInitialButton->SetParent(NULL);
		AurorerInitialButton->Delete();
		AurorerInitialButton = NULL;
	}
	if (ReportMultiColumnList != NULL)
	{
		ReportMultiColumnList->SetParent(NULL);
		ReportMultiColumnList->Delete();
		ReportMultiColumnList = NULL;

	}
	if (VirtualDisplayWidget != NULL)
	{
		VirtualDisplayWidget->SetParent(NULL);
		VirtualDisplayWidget->Delete();
		VirtualDisplayWidget = NULL;
	}
	if (CalibrationBeginButton != NULL)
	{
		CalibrationBeginButton->SetParent(NULL);
		CalibrationBeginButton->Delete();
		CalibrationBeginButton = NULL;
	}
	if (CalibrationStopButton != NULL)
	{
		CalibrationStopButton->SetParent(NULL);
		CalibrationStopButton->Delete();
		CalibrationStopButton = NULL;
	}
	if (SampleNumLabel != NULL)
	{
		SampleNumLabel->SetParent(NULL);
		SampleNumLabel->Delete();
		SampleNumLabel = NULL;
	}
	if (XOffsetEntry != NULL)
	{
		XOffsetEntry->SetParent(NULL);
		XOffsetEntry->Delete();
		XOffsetEntry = NULL;
	}
	if (YOffsetEntry != NULL)
	{
		YOffsetEntry->SetParent(NULL);
		YOffsetEntry->Delete();
		YOffsetEntry = NULL;
	}
	if (ZOffsetEntry != NULL)
	{
		ZOffsetEntry->SetParent(NULL);
		ZOffsetEntry->Delete();
		ZOffsetEntry = NULL;
	}

	if (MySlicerViewerWidget != NULL)
	{
		MySlicerViewerWidget->SetParent(NULL);
		MySlicerViewerWidget->Delete();
		MySlicerViewerWidget = NULL;
	}

	if (EndoscopeWindow1 != NULL)
	{
		EndoscopeWindow1->SetParent(NULL);
		EndoscopeWindow1->Delete();
		EndoscopeWindow1 = NULL;
	}

	if (EndoscopeWindow2 != NULL)
	{
		EndoscopeWindow2->SetParent(NULL);
		EndoscopeWindow2->Delete();
		EndoscopeWindow2 = NULL;
	}

	if (TextMappingButton != NULL)
	{
		TextMappingButton->SetParent(NULL);
		TextMappingButton->Delete();
		TextMappingButton = NULL;
	}
	if (SaveImageButton != NULL)
	{
		SaveImageButton->SetParent(NULL);
		SaveImageButton->Delete();
		SaveImageButton = NULL;
	}
	
	SetAndObserveESLogic(NULL);
	SetESLogic(NULL);
	this->Built = false;
}


//---------------------------------------------------------------------------
void EndoscopeGUI::PrintSelf ( ostream& os, vtkIndent indent )
{
	this->vtkObject::PrintSelf ( os, indent );

	os << indent << "TestGUI: " << this->GetClassName ( ) << "\n";
	//os << indent << "Logic: " << this->GetLogic ( ) << "\n";
	// print widgets?
}



//---------------------------------------------------------------------------
void EndoscopeGUI::RemoveGUIObservers ( )
{
	CaptureStartButton->RemoveObserver(GetGUICallbackCommand());
	CaptureStopButton->RemoveObserver(GetGUICallbackCommand());
	OpenDeviceButton->RemoveObserver(GetGUICallbackCommand());
	CloseDeviceButton->RemoveObserver(GetGUICallbackCommand());
	AurorerInitialButton->RemoveObserver(GetGUICallbackCommand());
	StartTrackingButton->RemoveObserver(GetGUICallbackCommand());
	StopTrackingButton->RemoveObserver(GetGUICallbackCommand());
	CalibrationBeginButton->RemoveObserver(GetGUICallbackCommand());
	CalibrationStopButton->RemoveObserver(GetGUICallbackCommand());
	TextMappingButton->RemoveObserver(GetGUICallbackCommand());
	SaveImageButton->RemoveObserver(GetGUICallbackCommand());

}

//---------------------------------------------------------------------------
void EndoscopeGUI::AddGUIObservers ( )
{

	CaptureStartButton->AddObserver(vtkKWPushButton::InvokedEvent, this->GetGUICallbackCommand());
	CaptureStopButton->AddObserver(vtkKWPushButton::InvokedEvent, this->GetGUICallbackCommand());
	OpenDeviceButton->AddObserver(vtkKWPushButton::InvokedEvent, this->GetGUICallbackCommand());
	CloseDeviceButton->AddObserver(vtkKWPushButton::InvokedEvent, this->GetGUICallbackCommand());
	AurorerInitialButton->AddObserver(vtkKWPushButton::InvokedEvent, this->GetGUICallbackCommand());
	StartTrackingButton->AddObserver(vtkKWPushButton::InvokedEvent, this->GetGUICallbackCommand());
	StopTrackingButton->AddObserver(vtkKWPushButton::InvokedEvent, this->GetGUICallbackCommand());

	CalibrationBeginButton->AddObserver(vtkKWPushButton::InvokedEvent, this->GetGUICallbackCommand());
	CalibrationStopButton->AddObserver(vtkKWPushButton::InvokedEvent, this->GetGUICallbackCommand());
	TextMappingButton->AddObserver(vtkKWPushButton::InvokedEvent, this->GetGUICallbackCommand());
	SaveImageButton->AddObserver(vtkKWPushButton::InvokedEvent, this->GetGUICallbackCommand());

}

//---------------------------------------------------------------------------
void EndoscopeGUI::ProcessGUIEvents ( vtkObject *caller,
								unsigned long event, void *callData )
{
	vtkSlicerApplication * app = (vtkSlicerApplication *)GetApplication();
	
	if (event == vtkKWPushButton::InvokedEvent)
	{
		if (caller == SaveImageButton)
		{
			vtkBMPWriter * bmpWriter = vtkBMPWriter::New();
			clock_t t = clock();
			std::stringstream sst;
			sst << USER_DATA << "SaveImages//" << t << ".bmp";
			bmpWriter->SetFileName(sst.str().c_str());
			bmpWriter->SetInput(EndoscopeView->GetRenderWidget()->GetImageData());
			bmpWriter->Write();
			bmpWriter->Delete();
		}
		if (caller == TextMappingButton)
		{
			// here do some texture mapping tests
			vtkCollection * collection = GetMRMLScene()->GetNodesByName("textureTest");
			if (collection->GetNumberOfItems() != 0)
			{
				vtkMRMLModelNode * node = vtkMRMLModelNode::SafeDownCast(collection->GetItemAsObject(0));
				if (node)
				{
					vtkMRMLModelDisplayNode * dnode = vtkMRMLModelDisplayNode::SafeDownCast(node->GetDisplayNode());
					if (dnode)
					{
						vtkTexureMappingByOrientation * textureMap = vtkTexureMappingByOrientation::New();
						vtkPolyData * polyData = node->GetPolyData();
						textureMap->SetInput(polyData);
						textureMap->Update();
						node->SetAndObservePolyData(vtkPolyData::SafeDownCast(textureMap->GetOutput()));
						dnode->SetAndObserveTextureImageData(EndoscopeView->GetRenderWidget()->GetImageData());
						textureMap->Delete();
					}
				}
			}
		}
		if (caller == OpenDeviceButton)
		{
			ESLogic->OpenDevice("IFIMGMEM1");
			OpenDeviceButton->SetStateToDisabled();
			CaptureStartButton->SetStateToNormal();
			CaptureStopButton->SetStateToDisabled();
			CloseDeviceButton->SetStateToNormal();
			vtkCollection * collection =  GetMRMLScene()->GetNodesByName("EndoscopeImage");
			if (collection->GetNumberOfItems() == 0)
			{
			
				vtkMRMLImageNode * imageNode = vtkMRMLImageNode::New();				
				imageNode->SetScene(GetMRMLScene());

				vtkMRMLEndoscopeImageDisplayNode1 * imageDisplayNode1 = vtkMRMLEndoscopeImageDisplayNode1::New();
				imageDisplayNode1->SetName("EndoscopeDisplayImage1");
				vtkMRMLEndoscopeImageDisplayNode2 * imageDisplayNode2 = vtkMRMLEndoscopeImageDisplayNode2::New();
				imageDisplayNode2->SetName("EndoscopeDisplayImage2");
				vtkMRMLEndoscopeImageDisplayNode3 * imageDisplayNode3 = vtkMRMLEndoscopeImageDisplayNode3::New();
				imageDisplayNode3->SetName("EndoscopeDisplayImage3");
				imageDisplayNode3->SetVisibility(0);

				imageDisplayNode1->SetScene(GetMRMLScene());
				imageDisplayNode2->SetScene(GetMRMLScene());
				imageDisplayNode3->SetScene(GetMRMLScene());


				GetMRMLScene()->AddNodeNoNotify(imageDisplayNode1);
				GetMRMLScene()->AddNodeNoNotify(imageDisplayNode2);
				GetMRMLScene()->AddNodeNoNotify(imageDisplayNode3);

				imageNode->AddAndObserveDisplayNodeID(imageDisplayNode1->GetID());
				imageNode->AddAndObserveDisplayNodeID(imageDisplayNode2->GetID());
				imageNode->AddAndObserveDisplayNodeID(imageDisplayNode3->GetID());

				imageNode->SetAndObserveImageData(EndoscopeView->GetRenderWidget()->GetImageData());
				imageNode->SetName("EndoscopeImage");

				GetMRMLScene()->AddNode(imageNode);

				imageDisplayNode1->Delete();
				imageDisplayNode2->Delete();
				imageDisplayNode3->Delete();
				imageNode->Delete();
			}	
		}
		if (caller == CloseDeviceButton)
		{
			ESLogic->CloseDevice();
			CloseDeviceButton->SetStateToDisabled();
			OpenDeviceButton->SetStateToNormal();
			CaptureStartButton->SetStateToDisabled();
			CaptureStopButton->SetStateToDisabled();
		}
		if (caller == CaptureStartButton)
		{
				//ESLogic->StartCapture();
				CaptureStartButton->SetStateToDisabled();
				CloseDeviceButton->SetStateToDisabled();
				OpenDeviceButton->SetStateToDisabled();
				CaptureStopButton->SetStateToNormal();
				EndoscopeView->GetRenderWidget()->SetIsAnimation(true);
				TimerID = vtkKWTkUtilities::CreateTimerHandler(GetApplication(), 100, EndoscopeView->GetRenderWidget(), "Animation");
		}
		if (caller == CaptureStopButton)
		{
			//ESLogic->StopCapture();
			EndoscopeView->GetRenderWidget()->SetIsAnimation(false);
			CaptureStopButton->SetStateToDisabled();
			CaptureStartButton->SetStateToNormal();
			CloseDeviceButton->SetStateToNormal();
			OpenDeviceButton->SetStateToDisabled();
		}	
		if (caller == AurorerInitialButton)
		{
			if (ESLogic->InitializeAurorer())
			{
				StartTrackingButton->SetStateToNormal();
				StopTrackingButton->SetStateToNormal();
			}
			
		}
		if (caller == StartTrackingButton)
		{
			ESLogic->StartTracking();	
			AurorerInitialButton->SetStateToDisabled();
		}
		if (caller == StopTrackingButton)
		{
			ESLogic->StopTracking();	
			AurorerInitialButton->SetStateToNormal();
		}
		if (caller == CalibrationBeginButton)
		{
			
			ESLogic->IsCalibratingOn();
		}
		if (caller == CalibrationStopButton)
		{
			double offsetError[4];
			ESLogic->IsCalibratingOff();
			ESLogic->GetCalibrationResult(offsetError);
			XOffsetEntry->GetWidget()->SetValueAsDouble(offsetError[0]);
			YOffsetEntry->GetWidget()->SetValueAsDouble(offsetError[1]);
			ZOffsetEntry->GetWidget()->SetValueAsDouble(offsetError[2]);
			std::stringstream ss;
			ss << "EMS : " << offsetError[3];
			SampleNumLabel->SetText(ss.str().c_str());
		}
	}
}

//---------------------------------------------------------------------------
void EndoscopeGUI::ProcessLogicEvents ( vtkObject *caller,
								  unsigned long event, void *callData )
{
	// Fill in
	static int i;
	if (caller == ESLogic && event == vtkCommand::ModifiedEvent)
	{
		if (callData != NULL)
		{
			unsigned int num = * reinterpret_cast<unsigned int *>(callData);
			std::stringstream ss;
			ss << num << " samples";
			SampleNumLabel->SetText(ss.str().c_str());
		}
		
	}

}

//---------------------------------------------------------------------------
void EndoscopeGUI::ProcessMRMLEvents ( vtkObject *caller,
								 unsigned long event, void *callData )
{
	// Fill in
	if (vtkMRMLImageNode::SafeDownCast(caller)  && event == vtkMRMLImageNode::ImageDataModifiedEvent)
	{
		EndoscopeWindow1->Render();
		EndoscopeWindow2->Render();
	}
	if (caller == GetMRMLScene() && event == vtkMRMLScene::NodeRemovedEvent)
	{
		vtkMRMLNode * nd = reinterpret_cast<vtkMRMLNode *> (callData);
		vtkMRMLImageNode * node = vtkMRMLImageNode::SafeDownCast(nd);
		if (node)
		{
			node->RemoveObserver(this->MRMLCallbackCommand);
		}

	}
	if (caller == GetMRMLScene() && event == vtkMRMLScene::NodeAddedEvent)
	{
		vtkMRMLNode * nd = reinterpret_cast<vtkMRMLNode *> (callData);
		vtkMRMLImageNode * node = vtkMRMLImageNode::SafeDownCast(nd);
		if (node)
		{	
			node->AddObserver(vtkMRMLImageNode::ImageDataModifiedEvent, this->MRMLCallbackCommand);
			
			for (int i = 0; i < node->GetNumberOfDisplayNodes(); ++i)
			{
				
				vtkMRMLImageDisplayNode * dnode = vtkMRMLImageDisplayNode::SafeDownCast(node->GetNthDisplayNode(i));
				if (dnode)
				{
					if (strcmp(dnode->GetName(), "EndoscopeDisplayImage1") && strcmp(dnode->GetName(), "EndoscopeDisplayImage2") )
						continue;
					vtkImageMapper * ImageMapper = vtkImageMapper::New();
					ImageMapper->SetInput(dnode->GetImageData());
					ImageMapper->SetColorWindow(255);
					ImageMapper->SetColorLevel(127.5);
					vtkKWRenderWidget * EndoscopeWindow = vtkMRMLEndoscopeImageDisplayNode1::SafeDownCast(dnode) ?
																						EndoscopeWindow1 : EndoscopeWindow2;
					vtkActor2DCollection * Collection = EndoscopeWindow->GetRenderer()->GetActors2D();
					vtkActor2D * Actor2D = NULL;
					if (Collection->GetNumberOfItems() == 0)
					{
						Actor2D= vtkActor2D::New();
						Actor2D->SetMapper(ImageMapper);
						EndoscopeWindow->GetRenderer()->AddActor2D(Actor2D);
						Actor2D->Delete();
					}
					else
					{
						Actor2D = vtkActor2D::SafeDownCast(Collection->GetItemAsObject(0));
						if (Actor2D)
							Actor2D->SetMapper(ImageMapper);
					}
					ImageMapper->Delete();
					EndoscopeWindow->Render();
				}
			}
			
		}
	}

}



//---------------------------------------------------------------------------
void EndoscopeGUI::CreateModuleEventBindings ( )
{
}

//---------------------------------------------------------------------------
void EndoscopeGUI::ReleaseModuleEventBindings ( )
{

}




//---------------------------------------------------------------------------
void EndoscopeGUI::Enter ( )
{
	if ( this->Built == false )
	{
		this->BuildGUI();
		this->Built = true;
		this->AddGUIObservers();
		this->AddObserver ( vtkSlicerModuleGUI::ModuleSelectedEvent, (vtkCommand *)this->ApplicationGUI->GetGUICallbackCommand() );
	}
	this->EndoscopeIP->Raise();
	GetApplicationGUI()->GetMainSlicerWindow()->SetSecondaryPanelVisibility(0);
	this->CreateModuleEventBindings();
}



//---------------------------------------------------------------------------
void EndoscopeGUI::Exit ( )
{
	this->ReleaseModuleEventBindings();
	vtkSlicerApplication *app = (vtkSlicerApplication *)this->GetApplication();
	/*app->GetApplicationGUI()->GetMainSlicerWindow()
		->GetViewUserInterfaceManager()->HidePanel(this->EndoscopeIP);*/
	
}



//---------------------------------------------------------------------------
void EndoscopeGUI::TearDownGUI ( )
{
	this->Exit();
	if ( this->Built )
	{
		this->RemoveGUIObservers();
	}
}

//---------------------------------------------------------------------------
void EndoscopeGUI::BuildGUI ( )
{

	vtkSlicerApplication *app = (vtkSlicerApplication *)this->GetApplication();
	vtkKWFrame* Frame = app->GetApplicationGUI()->GetMainSlicerWindow()->GetViewPanelFrame();
	this->EndoscopeView = vtkEndoscopeWidget::New();
	this->EndoscopeView->SetParent(Frame);
	this->EndoscopeView->SetApplication(app);
	this->EndoscopeView->SetESLogic(ESLogic);
	this->EndoscopeView->Create();
	this->VirtualDisplayWidget = vtkVirtualDisplayWidget::New();
	vtkIntArray *events = vtkIntArray::New();
	events->InsertNextValue(vtkMRMLScene::SceneCloseEvent);
	events->InsertNextValue(vtkMRMLScene::NewSceneEvent);
	events->InsertNextValue(vtkMRMLScene::NodeAddedEvent);
	events->InsertNextValue(vtkMRMLScene::NodeRemovedEvent);
	events->InsertNextValue(vtkCommand::ModifiedEvent);
	this->VirtualDisplayWidget->SetAndObserveMRMLSceneEvents (this->MRMLScene, events );
	this->VirtualDisplayWidget->SetParent(Frame);
	this->VirtualDisplayWidget->SetApplication(app);
	this->VirtualDisplayWidget->SetLogic(ESLogic);	
	this->VirtualDisplayWidget->Create();
	this->VirtualDisplayWidget->UpdateFromMRML();
	events->Delete();


	//this->MySlicerViewerWidget = vtkSlicerViewerWidget::New ( );
	//this->MySlicerViewerWidget->SetApplication( app );
	//this->MySlicerViewerWidget->SetParent(Frame);

	//// add events
	//vtkIntArray *events = vtkIntArray::New();
	//events->InsertNextValue(vtkMRMLScene::SceneCloseEvent);
	//events->InsertNextValue(vtkMRMLScene::NewSceneEvent);
	//events->InsertNextValue(vtkMRMLScene::NodeAddedEvent);
	//events->InsertNextValue(vtkMRMLScene::NodeRemovedEvent);
	//events->InsertNextValue(vtkCommand::ModifiedEvent);
	//this->MySlicerViewerWidget->SetAndObserveMRMLSceneEvents (this->MRMLScene, events );

	//events->Delete();
	//this->MySlicerViewerWidget->Create();
	//this->MySlicerViewerWidget->GetMainViewer()->SetRendererBackgroundColor (0.3, 0.4, 0.7 );
	//this->MySlicerViewerWidget->UpdateFromMRML();
	//this->MySlicerViewerWidget->SetApplicationLogic ( this->GetApplicationLogic () );


	EndoscopeIP = vtkKWUserInterfacePanel::New();
	EndoscopeIP->SetUserInterfaceManager(app->GetApplicationGUI()->GetMainSlicerWindow()
																->GetViewUserInterfaceManager());
	EndoscopeIP->AddPage("VirtualScene", "Welcome to Virtual World");
	EndoscopeIP->AddPage("Endoscope", "Endoscope Image Handling");
	
	//this->MySlicerViewerWidget->PackWidget(EndoscopeIP->GetPageWidget("VirtualScene"));
	this->EndoscopeView->Pack(EndoscopeIP->GetPageWidget("Endoscope"));
	app->Script("pack %s -in %s -expand true -fill both", VirtualDisplayWidget->GetWidgetName(), 
		EndoscopeIP->GetPageWidget("VirtualScene")->GetWidgetName());
	// ---
	// MODULE GUI FRAME 
	// configure a page for a model loading UI for now.
	// later, switch on the modulesButton in the SlicerControlGUI
	// ---
	// create a page

	this->UIPanel->AddPage ( "Endoscope", "Endoscope Module", NULL );
	
	// Define your help text and build the help frame here.
	const char *help = "Endoscope Module is under development... ";
	const char *about = "This work was supported by BMPE. See <a>http://www.google.org</a> for details. ";
	vtkKWWidget *page = this->UIPanel->GetPageWidget ( "Endoscope" );
	this->BuildHelpAndAboutFrame ( page, help, about );

	vtkSlicerModuleCollapsibleFrame *aurorerControlFrame = vtkSlicerModuleCollapsibleFrame::New ( );
	aurorerControlFrame->SetParent ( this->UIPanel->GetPageWidget ( "Endoscope" ) );
	aurorerControlFrame->Create ( );
	aurorerControlFrame->CollapseFrame();
	aurorerControlFrame->SetLabelText ("Aurorer Control");
	app->Script ( "pack %s -side top -anchor nw -fill x -padx 2 -pady 2 -in %s",
		aurorerControlFrame->GetWidgetName(), this->UIPanel->GetPageWidget("Endoscope")->GetWidgetName());
	vtkKWFrame * ButtonFrame = vtkKWFrame::New();
	ButtonFrame->SetParent(aurorerControlFrame->GetFrame());
	ButtonFrame->Create();
	AurorerInitialButton = vtkKWPushButton::New();
	AurorerInitialButton->SetParent(ButtonFrame);
	AurorerInitialButton->Create();
	AurorerInitialButton->SetText("Initialize Aurorer");
	app->Script("grid %s -column 0 -row 0 -padx 5 -pady 5", AurorerInitialButton->GetWidgetName());
	
	StartTrackingButton = vtkKWPushButton::New();
	StartTrackingButton->SetParent(ButtonFrame);
	StartTrackingButton->Create();
	StartTrackingButton->SetText("Start Tracking");
	app->Script("grid %s -column 1 -row 0 -padx 5 -pady 5", StartTrackingButton->GetWidgetName());

	StopTrackingButton = vtkKWPushButton::New();
	StopTrackingButton->SetParent(ButtonFrame);
	StopTrackingButton->Create();
	StopTrackingButton->SetText("Stop Tracking");
	app->Script("grid %s -column 2 -row 0 -padx 5 -pady 5", StopTrackingButton->GetWidgetName());
	app->Script("pack %s -side top -anchor nw -expand 1 -fill x", ButtonFrame->GetWidgetName());
	ButtonFrame->Delete();
	StartTrackingButton->SetStateToDisabled();
	StopTrackingButton->SetStateToDisabled();
	
	//////////////////////////////////////////////////////////////////////////
	ReportMultiColumnList = vtkKWMultiColumnListWithScrollbars::New();
	ReportMultiColumnList->SetParent(aurorerControlFrame->GetFrame());
	ReportMultiColumnList->Create();
	ReportMultiColumnList->GetWidget()->MovableColumnsOn();
	//ReportMultiColumnList->SetWidth(0);
	int col_index;

	// Add the columns (make some of them editable)
	col_index = ReportMultiColumnList->GetWidget()->AddColumn("Handle");
	//ReportMultiColumnList->GetWidget()->SetColumnWidth(col_index, 10);
	col_index = ReportMultiColumnList->GetWidget()->AddColumn("Port");
	//ReportMultiColumnList->GetWidget()->SetColumnWidth(col_index, 10);
	col_index = ReportMultiColumnList->GetWidget()->AddColumn("Tx");
	//ReportMultiColumnList->GetWidget()->SetColumnWidth(col_index, 10);

	col_index = ReportMultiColumnList->GetWidget()->AddColumn("Ty");

	col_index = ReportMultiColumnList->GetWidget()->AddColumn("Tz");

	col_index = ReportMultiColumnList->GetWidget()->AddColumn("Q0");

	col_index = ReportMultiColumnList->GetWidget()->AddColumn("Qx");

	col_index = ReportMultiColumnList->GetWidget()->AddColumn("Qy");

	col_index = ReportMultiColumnList->GetWidget()->AddColumn("Qz");

	col_index = ReportMultiColumnList->GetWidget()->AddColumn("Status");
	app->Script(
		"pack %s -side top -anchor nw -expand 1 -fill x", 
		ReportMultiColumnList->GetWidgetName());
	vtkKWFrame * calibrationFrame = vtkKWFrame::New();
	calibrationFrame->SetParent(aurorerControlFrame->GetFrame());
	calibrationFrame->Create();
	CalibrationBeginButton = vtkKWPushButton::New();
	CalibrationBeginButton->SetParent(calibrationFrame);
	CalibrationBeginButton->Create();
	CalibrationBeginButton->SetText("Begin Calibration");
	app->Script("grid %s -column 0 -row 0 -padx 5 -pady 5", CalibrationBeginButton->GetWidgetName());
	CalibrationStopButton = vtkKWPushButton::New();
	CalibrationStopButton->SetParent(calibrationFrame);
	CalibrationStopButton->Create();
	CalibrationStopButton->SetText("Stop Calibration");
	app->Script("grid %s -column 1 -row 0 -padx 5 -pady 5", CalibrationStopButton->GetWidgetName());
	SampleNumLabel = vtkKWLabel::New();
	SampleNumLabel->SetParent(calibrationFrame);
	SampleNumLabel->Create();
	SampleNumLabel->SetText("0 samples");
	SampleNumLabel->SetBackgroundColor(0, 1, 0);
	app->Script("grid %s -column 2 -row 0 -padx 5 -pady 5", SampleNumLabel->GetWidgetName());
    
	XOffsetEntry = vtkKWEntryWithLabel::New();
	XOffsetEntry->SetParent(calibrationFrame);
	XOffsetEntry->Create();
	XOffsetEntry->SetLabelText("x");
	XOffsetEntry->GetWidget()->SetValueAsDouble(0.0);
	XOffsetEntry->GetWidget()->SetWidth(10);
	app->Script("grid %s -column 0 -row 1 -padx 5 -pady 5", XOffsetEntry->GetWidgetName());

	YOffsetEntry = vtkKWEntryWithLabel::New();
	YOffsetEntry->SetParent(calibrationFrame);
	YOffsetEntry->Create();
	YOffsetEntry->SetLabelText("y");
	YOffsetEntry->GetWidget()->SetValueAsDouble(0.0);
	YOffsetEntry->GetWidget()->SetWidth(10);
	app->Script("grid %s -column 1 -row 1 -padx 5 -pady 5", YOffsetEntry->GetWidgetName());

	ZOffsetEntry = vtkKWEntryWithLabel::New();
	ZOffsetEntry->SetParent(calibrationFrame);
	ZOffsetEntry->Create();
	ZOffsetEntry->SetLabelText("z");
	ZOffsetEntry->GetWidget()->SetValueAsDouble(0.0);
	ZOffsetEntry->GetWidget()->SetWidth(10);
	app->Script("grid %s -column 2 -row 1 -padx 5 -pady 5", ZOffsetEntry->GetWidgetName());

	//CalibrationBeginButton->SetStateToDisabled();
	//CalibrationStopButton->SetStateToDisabled();
	
	app->Script("pack %s -side top -anchor nw -expand 1 -fill x", calibrationFrame->GetWidgetName());
	calibrationFrame->Delete();


	//////////////////////////////////////////////////////////////////////////
	// INSPECT FRAME
	vtkSlicerModuleCollapsibleFrame *displayModifyFrame = vtkSlicerModuleCollapsibleFrame::New ( );
	displayModifyFrame->SetParent ( this->UIPanel->GetPageWidget ( "Endoscope" ) );
	displayModifyFrame->Create ( );
	displayModifyFrame->ExpandFrame ( );
	displayModifyFrame->SetLabelText ("Image Acquisition Card");
	app->Script ( "pack %s -side top -anchor nw -fill x -padx 2 -pady 2 -in %s",
		displayModifyFrame->GetWidgetName(), this->UIPanel->GetPageWidget("Endoscope")->GetWidgetName());
	
	CaptureStartButton = vtkKWPushButton::New();
	CaptureStartButton->SetParent(displayModifyFrame->GetFrame());
	CaptureStartButton->Create();
	CaptureStartButton->SetText("Start Capture");

	CaptureStopButton = vtkKWPushButton::New();
	CaptureStopButton->SetParent(displayModifyFrame->GetFrame());
	CaptureStopButton->Create();
	CaptureStopButton->SetText("Stop Capture");

	OpenDeviceButton = vtkKWPushButton::New();
	OpenDeviceButton->SetParent(displayModifyFrame->GetFrame());
	OpenDeviceButton->Create();
	OpenDeviceButton->SetText("Open Device");

	CloseDeviceButton = vtkKWPushButton::New();
	CloseDeviceButton->SetParent(displayModifyFrame->GetFrame());
	CloseDeviceButton->Create();
	CloseDeviceButton->SetText("Close Device");
    // Initial State
	CloseDeviceButton->SetStateToDisabled();
	OpenDeviceButton->SetStateToNormal();
	CaptureStartButton->SetStateToDisabled();
	CaptureStopButton->SetStateToDisabled();

	SaveImageButton = vtkKWPushButton::New();
	SaveImageButton->SetParent(displayModifyFrame->GetFrame());
	SaveImageButton->Create();
	SaveImageButton->SetText("Save Image");

	app->Script("grid %s -column 0 -row 1 -padx 5 -pady 5 ", 
						CaptureStartButton->GetWidgetName());
	app->Script("grid %s -column 1 -row 1 -padx 5 -pady 5 ", 
		CaptureStopButton->GetWidgetName());

	app->Script("grid %s -column 0 -row 0 -padx 5 -pady 5 ", 
		OpenDeviceButton->GetWidgetName());
	app->Script("grid %s -column 1 -row 0 -padx 5 -pady 5 ", 
		CloseDeviceButton->GetWidgetName());
	app->Script("grid %s -column 2 -row 0 -padx 5 -pady 5 ", 
		SaveImageButton->GetWidgetName());

	//app->Script("grid %s -column 2 -row 0 -padx 5 -pady 5 ", 
	//	FrameFrequencyLabel->GetWidgetName());
	displayModifyFrame->Delete ( );
	aurorerControlFrame->Delete();

	vtkSlicerModuleCollapsibleFrame *modelManipulateFrame = vtkSlicerModuleCollapsibleFrame::New ( );
	modelManipulateFrame->SetParent ( this->UIPanel->GetPageWidget ( "Endoscope" ) );
	modelManipulateFrame->Create ( );
	modelManipulateFrame->ExpandFrame ( );
	modelManipulateFrame->SetLabelText ("Endoscope Window");
	app->Script ( "pack %s -side top -anchor nw -fill x -padx 2 -pady 2 -in %s",
		modelManipulateFrame->GetWidgetName(), this->UIPanel->GetPageWidget("Endoscope")->GetWidgetName());
	vtkKWFrameWithLabel * eframe1 = vtkKWFrameWithLabel::New();
	eframe1->SetParent(modelManipulateFrame->GetFrame());
	eframe1->Create();
	eframe1->SetLabelText("EndoscopeImage 1");
	app->Script ( "pack %s -side top -anchor nw -fill x -padx 2 -pady 2", eframe1->GetWidgetName());
	
	EndoscopeWindow1 = vtkKWRenderWidget::New();
	EndoscopeWindow1->SetParent(eframe1->GetFrame());
	EndoscopeWindow1->Create();
	EndoscopeWindow1->SetHeight(240);
	EndoscopeWindow1->SetWidth(320);
	EndoscopeWindow1->GetRenderer()->SetBackground(0, 0, 0);
	app->Script("pack %s -side top -anchor c  -padx 2 -pady 2", EndoscopeWindow1->GetWidgetName());
	eframe1->Delete();

	vtkKWFrameWithLabel * eframe2 = vtkKWFrameWithLabel::New();
	eframe2->SetParent(modelManipulateFrame->GetFrame());
	eframe2->Create();
	eframe2->SetLabelText("EndoscopeImage 2");
	app->Script ( "pack %s -side top -anchor nw -fill x -padx 2 -pady 2", eframe2->GetWidgetName());

	EndoscopeWindow2 = vtkKWRenderWidget::New();
	EndoscopeWindow2->SetParent(eframe2->GetFrame());
	EndoscopeWindow2->Create();
	EndoscopeWindow2->SetHeight(240);
	EndoscopeWindow2->SetWidth(320);
	EndoscopeWindow2->GetRenderer()->SetBackground(0, 0, 0);
	app->Script("pack %s -side top -anchor c  -padx 2 -pady 2", EndoscopeWindow2->GetWidgetName());
	eframe2->Delete();
	modelManipulateFrame->Delete();

	vtkSlicerModuleCollapsibleFrame *textureMappingFrame = vtkSlicerModuleCollapsibleFrame::New ( );
	textureMappingFrame->SetParent ( this->UIPanel->GetPageWidget ( "Endoscope" ) );
	textureMappingFrame->Create ( );
	textureMappingFrame->ExpandFrame ( );
	textureMappingFrame->SetLabelText ("Texture Mapping");
	app->Script ( "pack %s -side top -anchor nw -fill x -padx 2 -pady 2 -in %s",
		textureMappingFrame->GetWidgetName(), this->UIPanel->GetPageWidget("Endoscope")->GetWidgetName());
	
	TextMappingButton = vtkKWPushButton::New();
	TextMappingButton->SetParent(textureMappingFrame->GetFrame());
	TextMappingButton->Create();
	TextMappingButton->SetText("Mapping Test");
	app->Script ("pack %s -side top -anchor nw  -padx 2 -pady 2", TextMappingButton->GetWidgetName());

	textureMappingFrame->Delete();

}


void EndoscopeGUI::SetAndObserveESLogic(EndoscopeLogic * logic)
{
	SetAndObserveLogic(vtkObjectPointer(&this->ESLogic), logic);
}

void EndoscopeGUI::SetESLogic(EndoscopeLogic * logic)
{
	SetLogic(vtkObjectPointer(&this->ESLogic), logic);
}
